#include <alt_types.h>
#include "ethernet.h"
#include "ipv4.h"
#include "arp.h"
#include "udp.h"
#include "eth_tx.h"
#include "eth_rx.h"
#include "../utility.h"


static alt_u64	cur_mac;
static alt_u64	smac;			//! MAC источника последнего проанализированного пакета
static alt_u64	dmac;			//! MAC назначения последнего проанализированного пакета
static alt_u16	etype;			//! Тип протокола

static alt_u8*	ask_frame;		//! Указатель на начало формируемого ответа, без ethernet заголовка
//static alt_u8*	payload;		//! Указатель на начало полезной нагрузки пакета
static alt_u16	frame_size;		//! Размер формируемого / сформированного пакета

alt_u8 ethernet_set_mac(alt_u64 mac)
{
	arp_set_mac(mac);
	cur_mac	= mac;
	return 0;
}

alt_u8 ethernet_set_ip(alt_u32 ip)
{
	ipv4_set_source_ip(ip);
	arp_set_ip(ip);

	return 0;
}

alt_u8 ethernet_set_ask_buf(alt_u8* ask_buf)
{
	ask_frame = ask_buf;
	return 0;
}

// Обработчик входных пакетов
alt_u8 ethernet_frame_parser(alt_u8* frame, alt_u16* ask_size)
{
	alt_u8 			err = 0;		// Код ошибки
	eth_header_t*	eth_header;		// Указатель на заголовок ethernet
	alt_u64			dmac;

	eth_header = (eth_header_t*)frame;

	smac	= ntoh48(eth_header->smac);
	dmac	= ntoh48(eth_header->dmac);
	etype	= ntoh16(eth_header->etype);

	// По умолчанию размер ответного пакета 0
	frame_size = 0;
	if ((dmac == cur_mac) || (dmac == 	0xFFFFFFFFFFFFLL))
	{
		switch (etype)
		{
		// Если это был запрос ARP.
		case ARP :
			// Адрес ответа формируем со смещением на ARP заголовок
			err = arp_create_ask(
					(void*)(frame + ETH_HEAD_SIZE),
					(void*)(ask_frame));
			if (err == 0)
			{
				*ask_size	= ARP_SIZE;
			}
			break;

		// Если это был пакет IPv4, надо его парсить
		case IP:
			err = ipv4_header_parser((void*)(frame + ETH_HEAD_SIZE));
			break;

		default	:
			err = 2;
			break;
		}	// END switch
	}
	else
	{
		err = 3;
	}

	return err;
}


alt_u64 ethernet_get_smac()
{
	return smac;
}

alt_u64 ethernet_get_dmac()
{

	return dmac;
}


alt_u16 ethernet_get_etype()
{

	return etype;
}
